﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

namespace LockCrypt.Core {
    public class Comparers {
        /// <summary>
        /// Compares entries in a dictionary by name.
        /// </summary>
        public class CultureInfoEnglishNameComparer : IComparer<DictionaryEntry> {
            CaseInsensitiveComparer comp = new CaseInsensitiveComparer();
            public int Compare(DictionaryEntry x, DictionaryEntry y) {
                return comp.Compare(((x.Value as CultureInfo) ?? CultureInfo.InvariantCulture).EnglishName,
                                    ((y.Value as CultureInfo) ?? CultureInfo.InvariantCulture).EnglishName);
            }
        }

        public class FieldEqualityComparer : IEqualityComparer<string> {
            public bool Equals(string x, string y) {
                return x.ToLowerInvariant().Equals(y.ToLowerInvariant());
            }
            public int GetHashCode(string obj) {
                return obj.ToLowerInvariant().GetHashCode();
            }
        }

        public class FieldComparer : IComparer<DictionaryEntry>, IComparer<IField> {
            public int Compare(DictionaryEntry x, DictionaryEntry y) {
                if(x.Value is IField && y.Value is IField) {
                    return ((IField)x.Value).SortIndex.CompareTo(((IField)y.Value).SortIndex);
                } else if(x.Key is int && y.Key is int) {
                    return ((int)x.Key).CompareTo((int)y.Key);
                } else {
                    return (x.Key ?? string.Empty).ToString().CompareTo((y.Key ?? string.Empty).ToString());
                }
            }

            public int Compare(IField x, IField y) {
                if(x == null) {
                    if(y == null) {
                        return 0;
                    } else {
                        return -1;
                    }
                } else if(y == null) {
                    return 1;
                } else {
                    return x.SortIndex.CompareTo(y.SortIndex);
                }
            }
        }

        /// <summary>
        /// Compares accounts by name.
        /// </summary>
        public class AccountComparer : IComparer<IAccount> {
            public int Compare(IAccount x, IAccount y) {
                if(x != null && y != null) {
                    try {
                        return string.Compare(x.Name, y.Name, true, System.Globalization.CultureInfo.InvariantCulture);
                    } catch(Exception ex) {
                        Console.WriteLine(ex.Message);
                    }
                } else if(x == null) {
                    return 1;
                }
                return -1;
            }
        }

        /// <summary>
        /// Compares groups by name.
        /// </summary>
        public class GroupComparer : IComparer<IGroup> {
            public int Compare(IGroup x, IGroup y) {
                if(x != null && y != null) {
                    try {
                        return string.Compare(x.Name, y.Name, true, System.Globalization.CultureInfo.InvariantCulture);
                    } catch(Exception ex) {
                        Console.WriteLine(ex.Message);
                    }
                } else if(x == null) {
                    return 1;
                }
                return -1;
            }
        }

        /// <summary>
        /// Compares templates by name.
        /// </summary>
        public class TemplateComparer : IComparer<ITemplate> {
            public int Compare(ITemplate x, ITemplate y) {
                if(x != null && y != null) {
                    try {
                        return string.Compare(x.Name, y.Name, true, System.Globalization.CultureInfo.InvariantCulture);
                    } catch(Exception ex) {
                        Console.WriteLine(ex.Message);
                    }
                } else if(x == null) {
                    return 1;
                }
                return -1;
            }
        }
    }
}
